package ws.server;

import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.websocket.OnClose;
import jakarta.websocket.OnMessage;
import jakarta.websocket.OnOpen;
import jakarta.websocket.Session;
import jakarta.websocket.server.ServerEndpoint;
import ws.entity.ChatInfo;

import java.io.IOException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.Map;

/**
 * @Author gjh
 * @Date 2025/9/18
 * @Description:
 */
@ServerEndpoint(value = "/connect",
        configurator = HandshakeHandler.class)
public class WebSocketServer {

    /**
     * 使用map集合维护一个用户列表
     * key是连接session的id
     * value是客户端的session对象
     */
    private static final Map<String,Session> users = new HashMap<>();

    /**
     * 用户上线
     * 每当由用户连接时，创建的session就保存到用户列表中
     * @param session
     */
    @OnOpen
    public void onOpen(Session session) {
        ChatInfo chatInfo = (ChatInfo) session.getUserProperties().get("chatInfo");
        users.put(chatInfo.getUsername(), session);
    }

    /**
     * 接收客户端发送的消息并执行群发（发送给所有的session）
     * @param session
     * @param message
     */
    @OnMessage
    public void onMessage(Session session, String message) {
        ChatInfo chatInfo = (ChatInfo) session.getUserProperties().get("chatInfo");
        ChatInfo info = new ChatInfo(chatInfo.getUsername(), message);
        sendAllUser(info);
    }

    /**
     * 群发
     */
    private void sendAllUser(ChatInfo info) {
        try {
            // 把 ChatInfo 转成 JSON
            String json = new ObjectMapper().writeValueAsString(info);

            // 遍历所有在线用户发送
            users.forEach((id, session) -> {
                session.getAsyncRemote().sendText(json);
            });

        } catch (Exception e) {
            throw new RuntimeException("发送失败", e);
        }
    }

    /**
     * 用户离线
     * 离线时，将从用户列表移除当前的session
     * @param session
     */
    @OnClose
    public void onClose(Session session) {
        //获取用户信息
        String user = (String) session.getUserProperties().get("user");
        users.remove(user);
    }
}